package output;

import java.io.*;

public class Display {
	
	public static String LOG_DIRECTORY = "log/";
	public static String LOG_EXTENSION = ".log";

	private BufferedWriter output;
	private BufferedWriter error;
	private String fileName;
	private String errFileName;
	private boolean verbose;
	
	public Display() {
		verbose = true;
	}
	
	public Display(String name) throws IOException {
		this(LOG_DIRECTORY + name + LOG_EXTENSION, LOG_DIRECTORY + name + "_error" + LOG_EXTENSION, true);
	}
	
	public Display(String fileName, String errFileName, boolean verbose) throws IOException {
		output = fileName == null ? null : new BufferedWriter(new FileWriter(new File(fileName)));
		this.fileName = fileName;
		error = errFileName == null ? null : new BufferedWriter(new FileWriter(new File(errFileName)));
		this.errFileName = errFileName;
		this.verbose = verbose;
	}
	
	public Display flush() {
		if (output != null)
			try {
				output.flush();
			} catch (IOException e) {
			}
		if (error != null)
			try {
				error.flush();
			} catch (IOException e) {
			}
		return this;
	}
	
	public void close() {
		if (output != null)
			try {
				output.close();
			} catch (IOException e) {
			}
		if (error != null)
			try {
				error.close();
			} catch (IOException e) {
			}
	}
	
	public Display out(String s) {
		if (s == null)
			s = "null";
		if (verbose)
			System.out.println(s);
		if (output != null) {
			try {
				output.write(s);
				output.append('\n');
			} catch (IOException e) {
			}
		}
		return this;
	}
	
	public Display outC(String s) {
		if (s == null)
			s = "null";
		if (verbose)
			System.out.print(s);
		if (output != null) {
			try {
				output.write(s);
			} catch (IOException e) {
			}
		}
		return this;
	}
	
	public Display eout(String s) {
		if (s == null)
			s = "null";
		if (verbose)
			System.err.println(s);
		if (error != null) {
			try {
				error.write(s);
				error.append('\n');
			} catch (IOException e) {
			}
		}
		return this;
	}
	
	public Display eoutC(String s) {
		if (s == null)
			s = "null";
		if (verbose)
			System.err.print(s);
		if (error != null) {
			try { 
				error.write(s);
			} catch (IOException e) {
			}
		}
		return this;
	}
	
	public static String bufferLeft(String s, char c, int size) {
		if (s == null || size <= 0)
			return "";
		StringBuilder sb = new StringBuilder(s);
		if (sb.length() > size)
			return sb.substring(sb.length()-size);
		while (sb.length() < size)
			sb.insert(0, c);
		return sb.toString();
	}
	
	public static String bufferRight(String s, char c, int size) {
		if (s == null || size <= 0)
			return "";
		StringBuilder sb = new StringBuilder(s);
		if (sb.length() > size)
			return sb.substring(sb.length()-size);
		while (sb.length() < size)
			sb.append(c);
		return sb.toString();
	}
	
	public static String bufferCenter(String s, char c, int size) {
		if (s == null || size <= 0)
			return "";
		StringBuilder sb = new StringBuilder(s);
		if (sb.length() > size)
			return sb.substring(sb.length()-size);
		boolean left = true;
		while (sb.length() < size) {
			if (left) {
				sb.insert(0, c);
				left = false;
			} else {
				sb.append(c);
				left = true;
			}
		}
		return sb.toString();
	}
	
	public static String underline(String s, String prefix) {
		if (s == null || s.length() == 0)
			return "";
		StringBuilder sb = new StringBuilder(prefix);
		int finalLength = s.length() + (prefix == null ? 0 : prefix.length());
		while (sb.length() < finalLength)
			sb.append('-');
		return sb.insert(0, "\n").insert(0, s).insert(0, prefix).append("\n").toString();
	}
	
	public static String box(String s, String prefix) {
		if (s == null || s.length() == 0)
			return "";
		StringBuilder sb = new StringBuilder(prefix);
		int count = 0;
		while (count++ < s.length() + 4)
			sb.append('#');
		sb.append("\n").append(prefix).append("# ").append(s).append(" #\n").append(prefix);
		count = 0;
		while (count++ < s.length() + 4)
			sb.append('#');
		return sb.append("\n").toString();
	}
	
	public static String wrapText(String s, int width, String prefix) {
		if (prefix == null)
			prefix = "";
		prefix = prefix.replaceAll("\t", "    ").replace("\n", "");
		if (s == null || s.length() == 0 || width <= prefix.length() + 1)
			throw new IllegalArgumentException();
		String[] arr = s.split("\n");
		String[][] darr = new String[arr.length][];
		for (int i=0;i<arr.length;i++)
			darr[i] = arr[i].split(" ");
		StringBuilder sb = new StringBuilder(prefix);
		int currLen = prefix.length();
		for (int i=0;i<darr.length;i++) {
			for (int j=0;j<darr[i].length;j++) {
				if (currLen+darr[i][j].length() < width) {
					currLen += darr[i][j].length() + 1;
					sb.append(darr[i][j]).append(" ");
				} else {
					currLen = prefix.length() + darr[i][j].length() + 1;
					sb.append("\n").append(prefix).append(darr[i][j]).append(" ");
				}
			}
			sb.append("\n").append(prefix);
			currLen = prefix.length();
		}
		return sb.toString();
	}
}
